<!DOCTYPE HTML>
<html>
<head>

    <title>La organización de las redes en Plan 9</title>

    <link rel="stylesheet" href="/pub/style/style.css" type="text/css" media="screen, handheld" title="default">
    <link rel="shortcut icon" href="/favicon.ico" type="image/vnd.microsoft.icon">

    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 


<meta name="verify-v1" content="6zEoK0WMlnLmIS/w7Pnh6+srZECHsvnMGN0kQmowSGk=" />
<meta name="google-site-verification" content="z5zCyEitNLNZmhVblsogrEiy6Acf0UZROsFMtLjioN4" />
<META name="y_key" content="49dff3fad5352458"><META name="y_key" content="5dc40bfee9494e98"><META name="y_key" content="b60a53d1fa98f4c8">
<meta name="msvalidate.01" content="5008C6E6B172BEB1F43E770296C3D560" />
<meta name="alexaVerifyID" content="l1vBNiKWqe9hCZhp0jV8OKPyjps" />

    

</head>
<body>

<div id="header">
    <div class="superHeader">
    <div class="left">
      <a href="http://quotes.cat-v.org">quotes</a> |
      <a href="http://doc.cat-v.org">docs</a> |
      <a href="http://repo.cat-v.org">repo</a> |
      <a href="http://go-lang.cat-v.org">golang</a> |
      <a href="http://sam.cat-v.org">sam</a> |
      <a href="http://man.cat-v.org">man</a> |
      <a href="http://acme.cat-v.org">acme</a> |
      <a href="http://glenda.cat-v.org">Glenda</a> |
      <a href="http://ninetimes.cat-v.org">9times</a> |
      <a href="http://harmful.cat-v.org">harmful</a> |
      <a href="http://9p.cat-v.org/">9P</a> |
      <a href="http://cat-v.org">cat-v.org</a>
    </div>

    <div class="right">

      <span class="doNotDisplay">Related sites:</span>
      | <a href="http://cat-v.org/update_log">site updates</a>
      | <a href="/sitemap">site map</a> |

    <script type="text/javascript">var addthis_disable_flash = true; var addthis_pub="uriell";</script>
    <a href="http://www.addthis.com/bookmark.php?v=20" onmouseover="return addthis_open(this, '', '[URL]', '[TITLE]')" onmouseout="addthis_close()" onclick="return addthis_sendto()"><img src="http://s7.addthis.com/static/btn/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a><script type="text/javascript" src="http://s7.addthis.com/js/200/addthis_widget.js"></script>
    </div>

    </div>

    <div class="midHeader">
    <h1 class="headerTitle"><a href="/">/sys/doc/ <span id="headerSubTitle">Documentation archive</span></a></h1>
    </div>
    
    <div class="subHeader"><br></div>
</div>

    <div id="side-bar">
        <div>
<p class="sideBarTitle">Sections:</p>
<ul>
<li><a href="/bell_labs/">&rsaquo; bell labs/</a></li>
<li><a href="/economics/">&rsaquo; economics/</a></li>
<li><a href="/henry_spencer/">&rsaquo; henry spencer/</a></li>
<li><a href="/inferno/">&rsaquo; inferno/</a></li>
<li><a href="/plan_9/" class="thisPage">&raquo;<i> plan 9/</i></a></li>
<li><ul>
<li><a href="/plan_9/1st_edition/">&rsaquo; 1st edition/</a></li>
<li><a href="/plan_9/2nd_edition/">&rsaquo; 2nd edition/</a></li>
<li><a href="/plan_9/3rd_edition/">&rsaquo; 3rd edition/</a></li>
<li><a href="/plan_9/4th_edition/">&rsaquo; 4th edition/</a></li>
<li><a href="/plan_9/IWP9/">&rsaquo; IWP9/</a></li>
<li><a href="/plan_9/blue_gene/">&rsaquo; blue gene/</a></li>
<li><a href="/plan_9/humour/">&rsaquo; humour/</a></li>
<li><a href="/plan_9/misc/">&rsaquo; misc/</a></li>
<li><a href="/plan_9/programming/">&rsaquo; programming/</a></li>
<li><a href="/plan_9/real_time/">&rsaquo; real time/</a></li>
<li><a href="/plan_9/translations/" class="thisPage">&raquo;<i> translations/</i></a></li>
<li><ul>
<li><a href="/plan_9/translations/russian/">&rsaquo; russian/</a></li>
<li><a href="/plan_9/translations/spanish/" class="thisPage">&raquo;<i> spanish/</i></a></li>
<li><ul>
<li><a href="/plan_9/translations/spanish/8">&rsaquo; 8</a></li>
<li><a href="/plan_9/translations/spanish/9">&rsaquo; 9</a></li>
<li><a href="/plan_9/translations/spanish/names">&rsaquo; names</a></li>
<li><a href="/plan_9/translations/spanish/net" class="thisPage">&raquo;<i> net</i></a></li>
</ul></li>
</ul></li>
</ul></li>
<li><a href="/political_science/">&rsaquo; political science/</a></li>
<li><a href="/programming/">&rsaquo; programming/</a></li>
<li><a href="/unix/">&rsaquo; unix/</a></li>
<li><a href="/xml/">&rsaquo; xml/</a></li>
</ul>
        </div>
        <div>
<ul>
<li><a href="http://man.cat-v.org/plan_9/">- Plan 9 Man Pages</a></li>
<li><a href="http://ninetimes.cat-v.org">- NineTimes News</a></li>
</ul>
        </div>
    </div>

<div id="main-copy">



<p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="margin-top: 0; margin-bottom: 0.21in"></p>

<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 12pt"><b>La organización de las redes en Plan 9</b></span></p>
<p style="margin-top: 0; margin-bottom: 0.21in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><i>Dave Presotto</i></span></p>
<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><i>Phil Winterbottom</i></span></p>
<p style="margin-top: 0; margin-bottom: 0.19in"></p>
<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><i>presotto,philw@plan9.bell-labs.com</i></span></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.08in"></p>
<p style="margin-top: 0; margin-bottom: 0.33in"></p>
<p style="line-height: 1.4em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><i>ABSTRACT</i></span></p>
<p style="margin-top: 0; margin-bottom: 0.19in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.00in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">En un sistema distribuido las redes son de importancia capital. Este documento describe la implementación, filosofía de diseño y organización del soporte de red en Plan 9. Hace referencia a los requerimientos de red para los sistemas distribuidos, nuestra implementación del nucleo, los nombres de red, los interfaces de usuario y el rendimiento. También observamos que gran parte de esta organización es importante en los sistemas actuales.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>1.
Introducción
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Plan 9 [Pike90] es un sistema portable distribuido, multi usuario, de propósito general implementado en una gran variedad de ordenadores y redes.
Lo que lo diferencia es su organización. El objetivo de esta organización fué reducir la administración y promover la compartición de recursos. Una de las claves de su éxito como sistema distribuido es la organización y gestión de sus redes.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Un sistema Plan 9 comprende servidores de ficheros, servidores de CPU y terminales. Los servidores de ficheros y de CPU son normalmente máquinas multiprocesador centrales con amplia memoria y conectados con redes de alta velocidad.
Una variedad de máquinas tipo estación de trabajo sirven como terminales de los servidores centrales usando varias redes y protocolos.
La arquitectura del sistema exige una jerarquía de velocidades de red acordes con las necesidades de sus componentes.
La conexión entre servidores de ficheros y servidores de CPU suele consistir en enlaces punto a punto de fibra óptica de banda ancha.
Las conexiones entre servidores y terminales suelen ser de velocidad media, como Ethernet [Met80] y Datakit [Fra80].
Conexiones de baja velocidad por Internet y el backbone de AT&amp;T sirve para usuarios de Oregon e Illinois.
Lineas básicas de datos RDSI y lineas serie a 9600 baudios proporcionan acceso a los usuarios en casa.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Puesto que los servidores de CPU y los terminales usan el mismo nucleo, los usuario pueden elegir ejecutar programas localmente en sus terminales o remotamente en los servidores de CPU.
La organización de Plan 9 oculta los detalles de la conectividad del sistema permitiendo tanto a usuarios como a administradores configurar su entorno para que sea tan distribuido o centralizado como ellos deseen.
Mediante comandos simples se puede construir un espacio de nombres local que abarque muchas máquinas y redes.
En el trabajo, los usuarios tienden a usar sus terminales como estaciones de trabajo, ejecutando programas interactivos localmente y reservando los servidores de CPU para datos o trabajos de computación intensiva, como compilar programas o ejecutar programas de ajedrez.
En casa, cuando se conectan a través de redes lentas, tienden a realizar más trabajo en los servidores de CPU para minimizar el tráfico por la linea.
El objetivo de la organización de red es proporcionar el mismo entorno al usuario estén donde estén los recursos que utilice.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>2.
Soporte de red del nucleo
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Las redes juegan un papel importante en un sistema distribuido. Esto es particularmente cierto en Plan 9, donde la mayoría de los recursos son proporcionados por servidores externos al nucleo.
La importancia del código de red dentro del nucleo se refleja en su tamaño: de sus 25.000 lineas de código, 12.500 son relativas a red y a protocolos. Constantemente se están agregando redes y la fracción de código de comunicaciones está creciendo.
Peor aún, el código de red es complejo. Las implementaciones de protocolos consisten casi por entero en sincronización y manejo dinámico de memoria, areas que demandan sutiles estrategias de recuperación de errores.
El nucleo actual soporta Datakit, enlaces de fibra óptica punto a punto, una suite de protocolos de Internet (IP) y un servicio de datos RDSI.
La variedad de redes y máquinas ha hecho surgir cuestiones no planteadas por otros sistemas que se ejecutan en hardware comercial y que solamente soportan Ethernet o FDDI.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>2.1.
El protocolo de sistema de ficheros
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Una idea central de Plan 9 es la representación de un recurso como un sistema de ficheros jerárquico.
Cada proceso ensambla una vista del sistema construyendo un 
</span><span style="font-size: 10pt"><i>espacio de nombres</i></span><span style="font-size: 10pt">
[Needham] que conecta sus recursos.
Los sistemas de ficheros no necesitan representar ficheros en disco; de hecho, la mayoría de los sistemas de ficheros de Plan 9 no tienen almacenamiento permanente.
Un sistema de ficheros típico representa dinámicamente algún recurso como un conjunto de conexiones de red o la tabla de procesos. La comunicación entre el nucleo, los drivers de dispositivos y los servidores de ficheros remotos o locales usa un protocolo llamado 9P. Dicho protocolo consiste en 17 tipos de mensajes, que describen operaciones sobre ficheros y directorios.
Los dispositivos residentes del nucleoy los drivers de protocolos usan una versión procedural del protocolo, mientras que los servidores de ficheros externos usan una forma RPC.
Casi todo el tráfico entre sistemas Plan 9 consiste en mensajes 9P. Este protocolo se vasa en varias propiedades del protoloco de transporte subyacente. Asume que los mensajes llegan de manera fiable, y en correcta secuencia, y que se preservan los delimitadores entre mensajes.
Cuando un protocolo no cumple estos requerimientos (por ejemplo, TCP no preserva los delimitadores) nosotros proporcionamos mecanismos para reorganizar los mensajes antes de dejar que el sistema los maneje.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Una estructura de datos del nucleo, el 
</span><span style="font-size: 10pt"><i>canal</i></span><span style="font-size: 10pt">
es un handle a un servidor de ficheros.
Las operaciones sobre un canal generan los mensajes 9P siguientes:
Los mensajes 
</span><span style="font-size: 10pt"><tt>session</tt></span><span style="font-size: 10pt">
y
</span><span style="font-size: 10pt"><tt>attach</tt></span><span style="font-size: 10pt">
autentican la conexión, establecida por medios externos a 9P, y validan a su usuario.
El resultado es un canal autenticado que hace referencia a la raíz del servidor.
El mensaje
</span><span style="font-size: 10pt"><tt>clone</tt></span><span style="font-size: 10pt">
crea un nuevo canal idéntico a otro existente, de forma similar a como hace la llamada del sistema
</span><span style="font-size: 10pt"><tt>dup.</tt></span><span style="font-size: 10pt">
Un canal puede ser movido a un fichero del sistema usando el mensaje 
</span><span style="font-size: 10pt"><tt>walk</tt></span><span style="font-size: 10pt">
para descender cada nivel en la jerarquía.
Los mensajes
</span><span style="font-size: 10pt"><tt>stat</tt></span><span style="font-size: 10pt">
y
</span><span style="font-size: 10pt"><tt>wstat</tt></span><span style="font-size: 10pt">
leen y escriben los atributos del fichero referenciado por el canal.
El mensaje
</span><span style="font-size: 10pt"><tt>open</tt></span><span style="font-size: 10pt">
prepara un canal para una posterior operación mediante los mensajes
</span><span style="font-size: 10pt"><tt>read</tt></span><span style="font-size: 10pt">
y
</span><span style="font-size: 10pt"><tt>write</tt></span><span style="font-size: 10pt">
que acceden a los contenidos del fichero.
</span><span style="font-size: 10pt"><tt>Create</tt></span><span style="font-size: 10pt">
y
</span><span style="font-size: 10pt"><tt>remove</tt></span><span style="font-size: 10pt">
realizan las acciones que sus nombres indican sobre el fichero
El mensaje
</span><span style="font-size: 10pt"><tt>clunk</tt></span><span style="font-size: 10pt">
descarta un canal sin afectar al fichero.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Un servidor de ficheros residente del nucleo llamado
</span><span style="font-size: 10pt"><i>driver mount </i></span><span style="font-size: 10pt">
convierte la versión procedural de 9P en RPCs.
La llamada del sistema
</span><span style="font-size: 10pt"><i>mount</i></span><span style="font-size: 10pt">
proporciona un descriptor de fichero, que puede ser un pipe a un proceso de usuario o a una conexión de red con una máquina remota, para ser asociado con el punto de montaje.
Despues de un mount, las operaciones en el arbol de ficheros bajo el punto de montaje son enviadas como mensajes al servidor de ficheros.
El driver mount maneja buffers, empaqueta y desempaqueta parámetros de los mensajes, y desmultiplexa entre procesos que usan el servidor de ficheros.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>2.2.
Organización del nucleo
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">El código de red en el nucleo está dividido en tres capas: interfaz con el hardware, procesamiento de protocolos e interfaz con programas.
Un driver de dispositivo típicamente usa flujos para conectar las dos capas de interfaz. Modulos de flujos adicionales pueden ser incluidos en un dispositivo para procesar protocolos. Cada driver de dispositivo es un sistema de ficheros residente del nucleo que contiene solamente unos pocos ficheros: por ejemplo, representamos cada UART por medio de un fichero control y otro data.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Los dispositivos multiplexados presentan un interfaz de estructura un poco más compleja. Por ejemplo, el driver Ethernet LANCE sirve un árbol de ficheros de dos niveles (Figura 1) proporcionando
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">&#8729;  control y configuración de dispositivo
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">&#8729;  protocolos de nivel usuario como ARP
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">&#8729;  interfaces de diagnóstico para software de snooping
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">El directorio superior contiene un fichero
</span><span style="font-size: 10pt"><tt>clone</tt></span><span style="font-size: 10pt">
y un directorio para cada conexión, numerados desde
</span><span style="font-size: 10pt"><tt>1</tt></span><span style="font-size: 10pt">
a
</span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">.
Cada directorio de conexión corresponde a un tipo de paquete Ethernet.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">??????
Opening the
</span><span style="font-size: 10pt"><tt>clone</tt></span><span style="font-size: 10pt">
file finds an unused connection directory and opens its
</span><span style="font-size: 10pt"><tt>ctl.</tt></span><span style="font-size: 10pt">
file.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Abrir el fichero 
</span><span style="font-size: 10pt"><tt>clone</tt></span><span style="font-size: 10pt">
hace que se encuentre un directorio de una conexión no utilizada y que se abra su fichero
</span><span style="font-size: 10pt"><tt>ctl.</tt></span><span style="font-size: 10pt">
?????????
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Leyendo el fichero control se obtiene el numero de la conexión en ASCII; el proceso usuario puede usar este valor para construir el nombre del directorio de la conexión.
En cada directorio de conexión, ficheros llamados
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">,
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">,
</span><span style="font-size: 10pt"><tt>stats</tt></span><span style="font-size: 10pt">,
y
</span><span style="font-size: 10pt"><tt>type</tt></span><span style="font-size: 10pt">
proporcionan acceso a la conexión.
Escribir la cadena
</span><span style="font-size: 10pt"><tt>connect 2048</tt></span><span style="font-size: 10pt">
en el fichero 
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
hace que se ponga el tipo de paquete a 2048 y configura la conexión para recibir todos los paquetes IP enviados a la máquina. Las posteriores lecturas del fichero 
</span><span style="font-size: 10pt"><tt>type</tt></span><span style="font-size: 10pt">
obtendrán la cadena
</span><span style="font-size: 10pt"><tt>2048</tt></span><span style="font-size: 10pt">.
El fichero
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
accede al medio: leyéndolo se obtiene el siguiente paquete del tipo seleccionado. Escribiendo en él se pone se agrega a la cola un paquete para su transmisión, después de agregar una cabecera que contiene la dirección de origen y el tipo de paquete.
El fichero
</span><span style="font-size: 10pt"><tt>stats</tt></span><span style="font-size: 10pt">
devuelve un texto ASCII que contiene la dirección del interfaz, la cuenta de paquetes de entrada y de salida, las estadísticas de error, e información general sobre el estado del interfaz.
??????????
?????.so tree.pout
???????????
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Si varias conexiones en un interfaz están configuradas para un tipo concreto de paquete, cada una recibe una copia de los paquetes entrantes. El tipo especial de paquete
</span><span style="font-size: 10pt"><tt>-1</tt></span><span style="font-size: 10pt">
selecciona todos los paquetes.
Si se escriben las cadenas
</span><span style="font-size: 10pt"><tt>promiscuous</tt></span><span style="font-size: 10pt">
y
</span><span style="font-size: 10pt"><tt>connect</tt></span><span style="font-size: 10pt">
</span><span style="font-size: 10pt"><tt>-1</tt></span><span style="font-size: 10pt">
en el fichero
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
se configura una conversación para recibir todos los paquetes del Ethernet.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Aunque el interfaz del driver pueda parecer muy elaborado, la representación de un dispositivo como un conjunto de ficheros que usan cadenas ASCII para comunicarse tiene varias ventajas. Cualquier mecanismo que soporte acceso remoto a ficheros permite inmediatamente a una máquina remota utilizar nuestros interfaces como pasarela.
Usar cadenas ASCII para controlar el interfaz evita problemas de orden de byte y asegura una representación uniforme para dispositivos en la misma máquina e incluso permite que los dispositivos sean accedidos remotamente. Representar dispositivos diferentes con el mismo conjunto de ficheros permite que herramientas comunes sirvan para varias redes o interfaces.
Programas como 
</span><span style="font-size: 10pt"><tt>stty</tt></span><span style="font-size: 10pt">
son reemplazados por
</span><span style="font-size: 10pt"><tt>echo</tt></span><span style="font-size: 10pt">
y una redirección de la shell
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>2.3.
Dispositivos de protocolo
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Las conexiones de red se representan mediante pseudo-dispositivos llamados dispositivos de protocolo.
Hay drivers para dispositivos de protocolo para el protocolo URP Datakit y para cada uno de los protocolos de Internet, TCP, UDP e IL.
IL, que describimos más adelante, es un nuevo protocolo de comunicación usado por Plan 9 para transmitir RPC&rsquo;s de sistemas de ficheros.
Todos los dispositivos de protocolo parecen idénticos, así que los programas usuarios no contienen código específico de red.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Cada driver de dispositivo de protocolo sirve una estructura de directorios similar a la del driver de Ethernet.
El directorio superior contiene un fichero
</span><span style="font-size: 10pt"><tt>clone</tt></span><span style="font-size: 10pt">
y un directorio para cada conexión numeradas de
</span><span style="font-size: 10pt"><tt>0</tt></span><span style="font-size: 10pt">
a
</span><span style="font-size: 10pt"><tt>n</tt></span><span style="font-size: 10pt">.
Cada directorio de conexión contiene ficheros para controlar una conexión y para enviar y recibir información.
Un directorio de conexión TCP tiene el siguiente aspecto:
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Para establecer una conexión se siguen estos pasos:
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">1) El dispositivo clone del protocolo apropiado se abre para reservar una conexión no usada.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">2) El descriptor de fichero devuelto por la orden open apunta al fichero
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
de la nueva conexión.
Leyendo este fichero se obtiene una cadena ASCII que contiene el número de la conexión.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">3) Una cadena ASCII específica de la red y del protocolo se escribe en el fichero
</span><span style="font-size: 10pt"><tt>ctl.</tt></span><span style="font-size: 10pt">
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">4) El path del fichero
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
se construye usando el número de conexión.
Cuando el fichero
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
se abre, la conexión está establecida.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Un proceso puede leer y escribir este descriptor de fichero para enviar y recibir mensajes en la red.
Si el proceso abre el fichero
</span><span style="font-size: 10pt"><tt>listen</tt></span><span style="font-size: 10pt">
se bloquea hasta que reciba una llamada entrante.
Una cadena de dirección escrita en 
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
antes de abrir listen selecciona el puerto o servicio que el proceso está listo para aceptar.
Cuando se recibe una llamada, la apertura se completa y se devuelve un descriptor de fichero apuntando al fichero 
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
de la nueva conexión.
Leer del fichero
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
proporciona un número de conexión que se usa para construir el path del fichero
</span><span style="font-size: 10pt"><tt>data.</tt></span><span style="font-size: 10pt">
Una conexión permanece establecida mientras cualquiera de los ficheros del directorio de la misma están referenciados, o hasta que se recibe un close desde la red.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>2.4.
Corrientes
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Una
</span><span style="font-size: 10pt"><i>stream</i></span><span style="font-size: 10pt">
o corriente [Rit84a][Presotto] es un canal bidireccional que conecta un dispositivo (físico o no) con un proceso de usuario.El proceso de usuario inserta y retira datos en un lado de la corriente. Los procesos del nucleo que actúan en nombre de un dispositivo insertan datos al otro lado.
Los canales de comunicación asíncrona como pipes, conversaciones TCP, conversaciones Datakit, y lineas RS232 se implementan usando corrientes.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Una corriente comprende una lista lineal de 
</span><span style="font-size: 10pt"><i>módulos en proceso</i></span><span style="font-size: 10pt">.
Cada módulo tiene una corriente de subida (hacia el proceso) y una de bajada (hacia el dispositivo)
</span><span style="font-size: 10pt"><i>rutina put</i></span><span style="font-size: 10pt">.
Llamando a la rutina put del módulo en cualquiera de ambos lados se insertan datos en la corriente.
???????????
Cada módulo llama al siguiente para que envie datos hacia arriba o hacia abajo en la corriente.
Each module calls the succeeding one to send data up or down the stream.
??????????
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Una instancia de un módulo en proceso se representa por un par de 
</span><span style="font-size: 10pt"><i>colas,</i></span><span style="font-size: 10pt">
una para cada dirección.
Las colas apuntan a las rutinas put y pueden usarse para encolar información que va a pasarse por la corriente. Algunas rutinas put encolan los datos localmente y los envian a través de la corriente más tarde, bien sea por una llamada posterior o por un evento asíncrono como un temporizador de retransmisión o una interrupción de dispositivo.
Los módulos en proceso crean procesos ayudantes del nucleo que proporcionan un contexto para manejar los eventos asíncronos.Por ejemplo, un proceso ayudante del nucleo se despierta periodicamente para realizar cualquier retransmisión TCP necesaria.
????????
El uso de procesos del nucleo en lugar de rutinas de servicio que se ejecutan hasta que terminan difiere de la implementación de las corrientes en UNIX.
The use of kernel processes instead of serialized run-to-completion service routines
differs from the implementation of Unix streams.
????????
Las rutinas de servicio de UNIX no pueden usar ningún recurso bloqueante del nucleo y carecen de un estado local prolongado.
Los procesos ayudantes del nucleo resuelven estos problemas simplificando el código de las corrientes.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">No hay sincronización implícita en nuestras corrientes. Cada módulo en proceso debe asegurarse de que los procesos concurrentes que usan la corriente están sincronizados.
Esto maximiza la concurrencia, pero introduce la posibilidad de un bloqueo mutuo.
Sin embargo, los bloqueos mutuos se evitan fácilmente mediante la programación cuidadosa; hasta la fecha no han causado problemas.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">La información se representa por medio de listas enlazadas de estructuras del nucleo llamadas
</span><span style="font-size: 10pt"><i>bloques</i></span><span style="font-size: 10pt">.
Cada bloque contiene un tipo, algunas banderas de estado, y punteros a un buffer opcional.
Los buffers de los bloques pueden guardar datos o información de control, es decir, directivas para los módulos en proceso.
Los bloques y los buffers de bloque se asignan dinámicamente de la memoria del nucleo.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>2.4.1.
Interfaz de usuario
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Una corriente se representa a nivel de usuario por dos ficheros,
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
y
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">.
Los nombres pueden ser cambiados por el driver de dispositivo que use la corriente, como ya dijimos en el ejemplo del driver de UART. El primer proceso que abre cualquiera de ellos crea la corriente automáticamente.
El último close la destruye.
Escribiendo en el fichero 
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
????????
se copian datos en los bloques del nucleo y se pasan a la rutina put del primer módulo en proceso.
copies the data into kernel blocks and passes them to the downstream put routine of the first processing module.
?????????
Se garantiza que una escritura de menos de 32K cabe en un solo bloque. Las escrituras concurrentes en la misma corriente no están sincronizadas, aunque el tamaño de 34K asegura escrituras atómicas  para la mayoría de los protocolos.
El último bloque escrito es marcado con un delimitador para alertar a los módulos de la corriente que se ocupan de los límites de la escritura. La mayor parte de las veces, la primera rutina put llama a la segunda, la segunda a la tercera y así hasta que los datos salen. Como consecuencia, la mayoría de los datos salen sin necesidad de un cambio de contexto.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Leer del fichero
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
devuelve los datos encolados en lo alto de la corriente. La lectura termina cuando se alcanza la cuenta de lecturas o cuando se encuentra el final de un bloque delimitado. Un bloqueo de lectura por corriente asegura que solamente un proceso puede leer de una corriente a la vez, y garantiza que los bytes leidos llegan contiguos desde la corriente. 
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Al igual que las corrientes UNIX [Rit84a], las de Plan 9 pueden ser configuradas dinámicamente.
El sistema de corrientes intercepta e interpreta los siguientes bloques de control:
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 2.04in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>push</tt></span><span style="font-size: 10pt"> </span><span style="font-size: 10pt"><i>name</i></span><span style="font-size: 10pt">  agrega una instancia del modulo en proceso
</span><span style="font-size: 10pt"><i>name</i></span><span style="font-size: 10pt">
en lo alto de la corriente.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 2.04in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>pop</tt></span><span style="font-size: 10pt">    retira el módulo superior de la stream.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 2.04in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>hangup</tt></span><span style="font-size: 10pt"> ???????
envía un mensaje de colgar por la corriente desde el lado del dispositivo
sends a hangup message up the stream from the device end.
???????
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Otros bloques de control son específicos de cada módulo y son interpretados por cada modulo en proceso sobre la marcha.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">La enrevesada sintaxis y semántica de la llamada del sistema 
</span><span style="font-size: 10pt"><tt>ioctl</tt></span><span style="font-size: 10pt">
de UNIX nos convenció para eliminarla de Plan 9.
En realidad, 
</span><span style="font-size: 10pt"><tt>ioctl</tt></span><span style="font-size: 10pt">
es reemplazada por el fichero
</span><span style="font-size: 10pt"><tt>ctl.</tt></span><span style="font-size: 10pt">
Escribir en él
es idéntico a escribir en el fichero 
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
solo que los bloques son de tipo
</span><span style="font-size: 10pt"><i>control</i></span><span style="font-size: 10pt">.
Un módulo en proceso analiza cada bloque de control que ve. Los comandos en los bloques de control son cadenas ASCII, así que el orden de bytes no es un problema cuando un sistema controla corrientes en un espacio de nombres implementado en otro procesador. El tiempo para analizar bloques de control no es importante, puesto que las operaciones de control son raras.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>2.4.2.
Device Interface
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The module at the downstream end of the stream is part of a device interface.
The particulars of the interface vary with the device.
Most device interfaces consist of an interrupt routine, an output
put routine, and a kernel process.
The output put routine stages data for the
device and starts the device if it is stopped.
The interrupt routine wakes up the kernel process whenever
the device has input to be processed or needs more output staged.
The kernel process puts information up the stream or stages more data for output.
The division of labor among the different pieces varies depending on
how much must be done at interrupt level.
However, the interrupt routine may not allocate blocks or call
a put routine since both actions require a process context.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>2.4.3.
Multiplexing
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The conversations using a protocol device must be
multiplexed onto a single physical wire.
We push a multiplexer processing module
onto the physical device stream to group the conversations.
The device end modules on the conversations add the necessary header
onto downstream messages and then put them to the module downstream
of the multiplexer.
The multiplexing module looks at each message moving up its stream and
puts it to the correct conversation stream after stripping
the header controlling the demultiplexing.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">This is similar to the Unix implementation of multiplexer streams.
The major difference is that we have no general structure that
corresponds to a multiplexer.
Each attempt to produce a generalized multiplexer created a more complicated
structure and underlined the basic difficulty of generalizing this mechanism.
We now code each multiplexer from scratch and favor simplicity over
generality.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>2.4.4.
Reflections
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Despite five year&rsquo;s experience and the efforts of many programmers,
we remain dissatisfied with the stream mechanism.
Performance is not an issue;
the time to process protocols and drive
device interfaces continues to dwarf the
time spent allocating, freeing, and moving blocks
of data.
However the mechanism remains inordinately
complex.
Much of the complexity results from our efforts
to make streams dynamically configurable, to
reuse processing modules on different devices
and to provide kernel synchronization
to ensure data structures
don&rsquo;t disappear under foot.
This is particularly irritating since we seldom use these properties.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Streams remain in our kernel because we are unable to
devise a better alternative.
Larry Peterson&rsquo;s X-kernel [Pet89a]
is the closest contender but
doesn&rsquo;t offer enough advantage to switch.
If we were to rewrite the streams code, we would probably statically
allocate resources for a large fixed number of conversations and burn
memory in favor of less complexity.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>3.
The IL Protocol
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">None of the standard IP protocols is suitable for transmission of
9P messages over an Ethernet or the Internet.
TCP has a high overhead and does not preserve delimiters.
UDP, while cheap, does not provide reliable sequenced delivery.
Early versions of the system used a custom protocol that was
efficient but unsatisfactory for internetwork transmission.
When we implemented IP, TCP, and UDP we looked around for a suitable
replacement with the following properties:
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">&#8729;  Reliable datagram service with sequenced delivery
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">&#8729;  Runs over IP
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">&#8729;  Low complexity, high performance
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.35in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">&#8729;  Adaptive timeouts
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">None met our needs so a new protocol was designed.
IL is a lightweight protocol designed to be encapsulated by IP.
It is a connection-based protocol
providing reliable transmission of sequenced messages between machines.
No provision is made for flow control since the protocol is designed to transport RPC
messages between client and server.
A small outstanding message window prevents too
many incoming messages from being buffered;
messages outside the window are discarded
and must be retransmitted.
Connection setup uses a two way handshake to generate
initial sequence numbers at each end of the connection;
subsequent data messages increment the
sequence numbers allowing
the receiver to resequence out of order messages. 
In contrast to other protocols, IL does not do blind retransmission.
If a message is lost and a timeout occurs, a query message is sent.
The query message is a small control message containing the current
sequence numbers as seen by the sender.
The receiver responds to a query by retransmitting missing messages.
This allows the protocol to behave well in congested networks,
where blind retransmission would cause further
congestion.
Like TCP, IL has adaptive timeouts.
A round-trip timer is used
to calculate acknowledge and retransmission times in terms of the network speed.
This allows the protocol to perform well on both the Internet and on local Ethernets.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">In keeping with the minimalist design of the rest of the kernel, IL is small.
The entire protocol is 847 lines of code, compared to 2200 lines for TCP.
IL is our protocol of choice.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>4.
Network Addressing
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">A uniform interface to protocols and devices is not sufficient to
support the transparency we require.
Since each network uses a different
addressing scheme,
the ASCII strings written to a control file have no common format.
As a result, every tool must know the specifics of the networks it
is capable of addressing.
Moreover, since each machine supplies a subset
of the available networks, each user must be aware of the networks supported
by every terminal and server machine.
This is obviously unacceptable.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Several possible solutions were considered and rejected; one deserves
more discussion.
We could have used a user-level file server
to represent the network name space as a Plan 9 file tree. 
This global naming scheme has been implemented in other distributed systems.
The file hierarchy provides paths to
directories representing network domains.
Each directory contains
files representing the names of the machines in that domain;
an example might be the path
</span><span style="font-size: 10pt"><tt>/net/name/usa/edu/mit/ai</tt></span><span style="font-size: 10pt">.
Each machine file contains information like the IP address of the machine.
We rejected this representation for several reasons.
First, it is hard to devise a hierarchy encompassing all representations
of the various network addressing schemes in a uniform manner.
Datakit and Ethernet address strings have nothing in common.
Second, the address of a machine is
often only a small part of the information required to connect to a service on
the machine.
For example, the IP protocols require symbolic service names to be mapped into
numeric port numbers, some of which are privileged and hence special.
Information of this sort is hard to represent in terms of file operations.
Finally, the size and number of the networks being represented burdens users with
an unacceptably large amount of information about the organization of the network
and its connectivity.
In this case the Plan 9 representation of a
resource as a file is not appropriate.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">If tools are to be network independent, a third-party server must resolve
network names.
A server on each machine, with local knowledge, can select the best network
for any particular destination machine or service.
Since the network devices present a common interface,
the only operation which differs between networks is name resolution.
A symbolic name must be translated to
the path of the clone file of a protocol
device and an ASCII address string to write to the
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
file.
A connection server (CS) provides this service.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>4.1.
Network Database
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">On most systems several
files such as
</span><span style="font-size: 10pt"><tt>/etc/hosts</tt></span><span style="font-size: 10pt">,
</span><span style="font-size: 10pt"><tt>/etc/networks</tt></span><span style="font-size: 10pt">,
</span><span style="font-size: 10pt"><tt>/etc/services</tt></span><span style="font-size: 10pt">,
</span><span style="font-size: 10pt"><tt>/etc/hosts.equiv</tt></span><span style="font-size: 10pt">,
</span><span style="font-size: 10pt"><tt>/etc/bootptab</tt></span><span style="font-size: 10pt">,
and
</span><span style="font-size: 10pt"><tt>/etc/named.d</tt></span><span style="font-size: 10pt">
hold network information.
Much time and effort is spent
administering these files and keeping
them mutually consistent.
Tools attempt to
automatically derive one or more of the files from
information in other files but maintenance continues to be
difficult and error prone.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Since we were writing an entirely new system, we were free to
try a simpler approach.
One database on a shared server contains all the information
needed for network administration.
Two ASCII files comprise the main database:
</span><span style="font-size: 10pt"><tt>/lib/ndb/local</tt></span><span style="font-size: 10pt">
contains locally administered information and
</span><span style="font-size: 10pt"><tt>/lib/ndb/global</tt></span><span style="font-size: 10pt">
contains information imported from elsewhere.
The files contain sets of attribute/value pairs of the form
</span><span style="font-size: 10pt"><tt></tt></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt></tt></span><span style="font-size: 10pt"></span><span style="font-size: 10pt"><i>attr</i></span><span style="font-size: 10pt"><tt>=</tt></span><span style="font-size: 10pt"><i>value</i></span><span style="font-size: 10pt">,
where
</span><span style="font-size: 10pt"><i>attr</i></span><span style="font-size: 10pt">
and
</span><span style="font-size: 10pt"><i>value</i></span><span style="font-size: 10pt">
are alphanumeric strings.
Systems are described by multi-line entries;
a header line at the left margin begins each entry followed by zero or more
indented attribute/value pairs specifying
names, addresses, properties, etc.
For example, the entry for our CPU server
specifies a domain name, an IP address, an Ethernet address,
a Datakit address, a boot file, and supported protocols.
</span></p><p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>4.2.
Connection Server
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">On each system a user level connection server process, CS, translates
symbolic names to addresses.
CS uses information about available networks, the network database, and
other servers (such as DNS) to translate names.
CS is a file server serving a single file,
</span><span style="font-size: 10pt"><tt>/net/cs</tt></span><span style="font-size: 10pt">.
A client writes a symbolic name to
</span><span style="font-size: 10pt"><tt>/net/cs</tt></span><span style="font-size: 10pt">
then reads one line for each matching destination reachable
from this system.
The lines are of the form
</span><span style="font-size: 10pt"><i>filename message</i></span><span style="font-size: 10pt">,
where
</span><span style="font-size: 10pt"><i>filename</i></span><span style="font-size: 10pt">
is the path of the clone file to open for a new connection and
</span><span style="font-size: 10pt"><i>message</i></span><span style="font-size: 10pt">
is the string to write to it to make the connection.
The following example illustrates this.
</span><span style="font-size: 10pt"><tt>Ndb/csquery</tt></span><span style="font-size: 10pt">
is a program that prompts for strings to write to
</span><span style="font-size: 10pt"><tt>/net/cs</tt></span><span style="font-size: 10pt">
and prints the replies.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">CS provides meta-name translation to perform complicated
searches.
The special network name
</span><span style="font-size: 10pt"><tt>net</tt></span><span style="font-size: 10pt">
selects any network in common between source and
destination supporting the specified service.
A host name of the form </span><span style="font-size: 10pt"><tt>$</tt></span><span style="font-size: 10pt"><i>attr</i></span><span style="font-size: 10pt">
is the name of an attribute in the network database.
The database search returns the value
of the matching attribute/value pair
most closely associated with the source host.
Most closely associated is defined on a per network basis.
For example, the symbolic name
</span><span style="font-size: 10pt"><tt>tcp!$auth!rexauth</tt></span><span style="font-size: 10pt">
causes CS to search for the
</span><span style="font-size: 10pt"><tt>auth</tt></span><span style="font-size: 10pt">
attribute in the database entry for the source system, then its
subnetwork (if there is one) and then its network.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Normally CS derives naming information from its database files.
For domain names however, CS first consults another user level
process, the domain name server (DNS).
If no DNS is reachable, CS relies on its own tables.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Like CS, the domain name server is a user level process providing
one file,
</span><span style="font-size: 10pt"><tt>/net/dns</tt></span><span style="font-size: 10pt">.
A client writes a request of the form
</span><span style="font-size: 10pt"><i>domain-name type</i></span><span style="font-size: 10pt">,
where
</span><span style="font-size: 10pt"><i>type</i></span><span style="font-size: 10pt">
is a domain name service resource record type.
DNS performs a recursive query through the
Internet domain name system producing one line
per resource record found.  The client reads
</span><span style="font-size: 10pt"><tt>/net/dns</tt></span><span style="font-size: 10pt">
to retrieve the records.
Like other domain name servers, DNS caches information
learned from the network.
DNS is implemented as a multi-process shared memory application
with separate processes listening for network and local requests.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>5.
Library routines
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The section on protocol devices described the details
of making and receiving connections across a network.
The dance is straightforward but tedious.
Library routines are provided to relieve
the programmer of the details.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>5.1.
Connecting
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The
</span><span style="font-size: 10pt"><tt>dial</tt></span><span style="font-size: 10pt">
library call establishes a connection to a remote destination.
It
returns an open file descriptor for the
</span><span style="font-size: 10pt"><tt>data</tt></span><span style="font-size: 10pt">
file in the connection directory.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.69in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>dest</tt></span><span style="font-size: 10pt">   is the symbolic name/address of the destination.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.69in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>local</tt></span><span style="font-size: 10pt">  is the local address.
Since most networks do not support this, it is
usually zero.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.69in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>dir</tt></span><span style="font-size: 10pt">    is a pointer to a buffer to hold the path name of the protocol directory
representing this connection.
</span><span style="font-size: 10pt"><tt>Dial</tt></span><span style="font-size: 10pt">
fills this buffer if the pointer is non-zero.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.69in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>cfdp</tt></span><span style="font-size: 10pt">   is a pointer to a file descriptor for the
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
file of the connection.
If the pointer is non-zero,
</span><span style="font-size: 10pt"><tt>dial</tt></span><span style="font-size: 10pt">
opens the control file and tucks the file descriptor here.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Most programs call
</span><span style="font-size: 10pt"><tt>dial</tt></span><span style="font-size: 10pt">
with a destination name and all other arguments zero.
</span><span style="font-size: 10pt"><tt>Dial</tt></span><span style="font-size: 10pt">
uses CS to
translate the symbolic name to all possible destination addresses
and attempts to connect to each in turn until one works.
Specifying the special name
</span><span style="font-size: 10pt"><tt>net</tt></span><span style="font-size: 10pt">
in the network portion of the destination
allows CS to pick a network/protocol in common
with the destination for which the requested service is valid.
For example, assume the system
</span><span style="font-size: 10pt"><tt>research.bell-labs.com</tt></span><span style="font-size: 10pt">
has the Datakit address
</span><span style="font-size: 10pt"><tt>nj/astro/research</tt></span><span style="font-size: 10pt">
and IP addresses
</span><span style="font-size: 10pt"><tt>135.104.117.5</tt></span><span style="font-size: 10pt">
and
</span><span style="font-size: 10pt"><tt>129.11.4.1</tt></span><span style="font-size: 10pt">.
The call
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Dial</tt></span><span style="font-size: 10pt">
accepts addresses instead of symbolic names.
For example, the destinations
</span><span style="font-size: 10pt"><tt>tcp!135.104.117.5!513</tt></span><span style="font-size: 10pt">
and
</span><span style="font-size: 10pt"><tt>tcp!research.bell-labs.com!login</tt></span><span style="font-size: 10pt">
are equivalent
references to the same machine.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>5.2.
Listening
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">A program uses
four routines to listen for incoming connections.
It first
</span><span style="font-size: 10pt"><tt>announce()</tt></span><span style="font-size: 10pt">s
its intention to receive connections,
then
</span><span style="font-size: 10pt"><tt>listen()</tt></span><span style="font-size: 10pt">s
for calls and finally
</span><span style="font-size: 10pt"><tt>accept()</tt></span><span style="font-size: 10pt">s
or
</span><span style="font-size: 10pt"><tt>reject()</tt></span><span style="font-size: 10pt">s
them.
</span><span style="font-size: 10pt"><tt>Announce</tt></span><span style="font-size: 10pt">
returns an open file descriptor for the
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
file of a connection and fills
</span><span style="font-size: 10pt"><tt>dir</tt></span><span style="font-size: 10pt">
with the
path of the protocol directory
for the announcement.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Listen</tt></span><span style="font-size: 10pt">
returns an open file descriptor for the
</span><span style="font-size: 10pt"><tt>ctl</tt></span><span style="font-size: 10pt">
file and fills
</span><span style="font-size: 10pt"><tt>ldir</tt></span><span style="font-size: 10pt">
with the path
of the protocol directory
for the received connection.
It is passed
</span><span style="font-size: 10pt"><tt>dir</tt></span><span style="font-size: 10pt">
from the announcement.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Accept</tt></span><span style="font-size: 10pt">
and
</span><span style="font-size: 10pt"><tt>reject</tt></span><span style="font-size: 10pt">
are called with the control file descriptor and
</span><span style="font-size: 10pt"><tt>ldir</tt></span><span style="font-size: 10pt">
returned by
</span><span style="font-size: 10pt"><tt>listen.</tt></span><span style="font-size: 10pt">
Some networks such as Datakit accept a reason for a rejection;
networks such as IP ignore the third argument.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The following code implements a typical TCP listener.
It announces itself, listens for connections, and forks a new
process for each.
The new process echoes data on the connection until the
remote end closes it.
The "*" in the symbolic name means the announcement is valid for
any addresses bound to the machine the program is run on.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>6.
User Level
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Communication between Plan 9 machines is done almost exclusively in
terms of 9P messages. Only the two services
</span><span style="font-size: 10pt"><tt>cpu</tt></span><span style="font-size: 10pt">
and
</span><span style="font-size: 10pt"><tt>exportfs</tt></span><span style="font-size: 10pt">
are used.
The
</span><span style="font-size: 10pt"><tt>cpu</tt></span><span style="font-size: 10pt">
service is analogous to
</span><span style="font-size: 10pt"><tt>rlogin</tt></span><span style="font-size: 10pt">.
However, rather than emulating a terminal session
across the network,
</span><span style="font-size: 10pt"><tt>cpu</tt></span><span style="font-size: 10pt">
creates a process on the remote machine whose name space is an analogue of the window
in which it was invoked.
</span><span style="font-size: 10pt"><tt>Exportfs</tt></span><span style="font-size: 10pt">
is a user level file server which allows a piece of name space to be
exported from machine to machine across a network. It is used by the
</span><span style="font-size: 10pt"><tt>cpu</tt></span><span style="font-size: 10pt">
command to serve the files in the terminal&rsquo;s name space when they are
accessed from the
cpu server.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">By convention, the protocol and device driver file systems are mounted in a
directory called
</span><span style="font-size: 10pt"><tt>/net</tt></span><span style="font-size: 10pt">.
Although the per-process name space allows users to configure an
arbitrary view of the system, in practice their profiles build
a conventional name space.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>6.1.
Exportfs
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Exportfs</tt></span><span style="font-size: 10pt">
is invoked by an incoming network call.
The
</span><span style="font-size: 10pt"><i>listener</i></span><span style="font-size: 10pt">
(the Plan 9 equivalent of
</span><span style="font-size: 10pt"><tt>inetd</tt></span><span style="font-size: 10pt">)
runs the profile of the user
requesting the service to construct a name space before starting
</span><span style="font-size: 10pt"><tt>exportfs</tt></span><span style="font-size: 10pt">.
After an initial protocol
establishes the root of the file tree being
exported,
the remote process mounts the connection,
allowing
</span><span style="font-size: 10pt"><tt>exportfs</tt></span><span style="font-size: 10pt">
to act as a relay file server. Operations in the imported file tree
are executed on the remote server and the results returned.
As a result
the name space of the remote machine appears to be exported into a
local file tree.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The
</span><span style="font-size: 10pt"><tt>import</tt></span><span style="font-size: 10pt">
command calls
</span><span style="font-size: 10pt"><tt>exportfs</tt></span><span style="font-size: 10pt">
on a remote machine, mounts the result in the local name space,
and
exits.
No local process is required to serve mounts;
9P messages are generated by the kernel&rsquo;s mount driver and sent
directly over the network.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><tt>Exportfs</tt></span><span style="font-size: 10pt">
must be multithreaded since the system calls
</span><span style="font-size: 10pt"><tt>open,</tt></span><span style="font-size: 10pt">
</span><span style="font-size: 10pt"><tt>read</tt></span><span style="font-size: 10pt">
and
</span><span style="font-size: 10pt"><tt>write</tt></span><span style="font-size: 10pt">
may block.
Plan 9 does not implement the 
</span><span style="font-size: 10pt"><tt>select</tt></span><span style="font-size: 10pt">
system call but does allow processes to share file descriptors,
memory and other resources.
</span><span style="font-size: 10pt"><tt>Exportfs</tt></span><span style="font-size: 10pt">
and the configurable name space
provide a means of sharing resources between machines.
It is a building block for constructing complex name spaces
served from many machines.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The simplicity of the interfaces encourages naive users to exploit the potential
of a richly connected environment.
Using these tools it is easy to gateway between networks.
For example a terminal with only a Datakit connection can import from the server
</span><span style="font-size: 10pt"><tt>helix</tt></span><span style="font-size: 10pt">:
</span></p><p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>6.2.
Ftpfs
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">We decided to make our interface to FTP
a file system rather than the traditional command.
Our command,
</span><span style="font-size: 10pt"><i>ftpfs,</i></span><span style="font-size: 10pt">
dials the FTP port of a remote system, prompts for login and password, sets image mode,
and mounts the remote file system onto
</span><span style="font-size: 10pt"><tt>/n/ftp</tt></span><span style="font-size: 10pt">.
Files and directories are cached to reduce traffic.
The cache is updated whenever a file is created.
Ftpfs works with TOPS-20, VMS, and various Unix flavors
as the remote system.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>7.
Cyclone Fiber Links
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The file servers and CPU servers are connected by
high-bandwidth
point-to-point links.
A link consists of two VME cards connected by a pair of optical
fibers.
The VME cards use 33MHz Intel 960 processors and AMD&rsquo;s TAXI
fiber transmitter/receivers to drive the lines at 125 Mbit/sec.
Software in the VME card reduces latency by copying messages from system memory
to fiber without intermediate buffering.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>8.
Performance
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">We measured both latency and throughput
of reading and writing bytes between two processes
for a number of different paths.
Measurements were made on two- and four-CPU SGI Power Series processors.
The CPUs are 25 MHz MIPS 3000s.
The latency is measured as the round trip time
for a byte sent from one process to another and
back again.
Throughput is measured using 16k writes from
one process to another.
</span></p><p style="margin-top: 0; margin-bottom: 0.08in"></p>
<center><img src="net0.png"></center>
</center>
<p style="margin-top: 0; margin-bottom: 0.02in"></p>

<p style="margin-top: 0; margin-bottom: 0.08in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>9.
Conclusion
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.35in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">The representation of all resources as file systems
coupled with an ASCII interface has proved more powerful
than we had originally imagined.
Resources can be used by any computer in our networks
independent of byte ordering or CPU type.
The connection server provides an elegant means
of decoupling tools from the networks they use.
Users successfully use Plan 9 without knowing the
topology of the system or the networks they use.
More information about 9P can be found in the Section 5 of the Plan 9 Programmer&rsquo;s
Manual, Volume I.
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"><b>10.
References
</b></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">[Pike90] R. Pike, D. Presotto, K. Thompson, H. Trickey,
&lsquo;&lsquo;Plan 9 from Bell Labs&rsquo;&rsquo;,
</span><span style="font-size: 10pt"><i>UKUUG Proc. of the Summer 1990 Conf. ,
London, England,
1990.
</i></span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">[Needham] R. Needham, &lsquo;&lsquo;Names&rsquo;&rsquo;, in
</span><span style="font-size: 10pt"><i>Distributed systems,
</i></span><span style="font-size: 10pt">S. Mullender, ed.,
Addison Wesley, 1989.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">[Presotto] D. Presotto, &lsquo;&lsquo;Multiprocessor Streams for Plan 9&rsquo;&rsquo;,
</span><span style="font-size: 10pt"><i>UKUUG Proc. of the Summer 1990 Conf. ,
</i></span><span style="font-size: 10pt">London, England, 1990.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">[Met80] R. Metcalfe, D. Boggs, C. Crane, E. Taf and J. Hupp, &lsquo;&lsquo;The
Ethernet Local Network: Three reports&rsquo;&rsquo;,
</span><span style="font-size: 10pt"><i>CSL-80-2,
</i></span><span style="font-size: 10pt">XEROX Palo Alto Research Center, February 1980.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">[Fra80] A. G. Fraser, &lsquo;&lsquo;Datakit - A Modular Network for Synchronous
and Asynchronous Traffic&rsquo;&rsquo;, 
</span><span style="font-size: 10pt"><i>Proc. Int&rsquo;l Conf. on Communication,
</i></span><span style="font-size: 10pt">Boston, June 1980.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">[Pet89a] L. Peterson, &lsquo;&lsquo;RPC in the X-Kernel: Evaluating new Design Techniques&rsquo;&rsquo;,
</span><span style="font-size: 10pt"><i>Proc. Twelfth Symp. on Op. Sys. Princ.,
</i></span><span style="font-size: 10pt">Litchfield Park, AZ, December 1990.
</span></p><p style="margin-top: 0; margin-bottom: 0.05in"></p>
<p style="line-height: 1.2em; margin-left: 1.40in; text-indent: 0.40in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">[Rit84a] D. M. Ritchie, &lsquo;&lsquo;A Stream Input-Output System&rsquo;&rsquo;,
</span><span style="font-size: 10pt"><i>AT&amp;T Bell Laboratories Technical Journal, 68(8),
</i></span><span style="font-size: 10pt">October 1984.
</span></p><p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.35in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt"></span><span style="font-size: 10pt"><b>Notes</b></span><span style="font-size: 10pt">
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>

<p style="line-height: 1.2em; margin-left: 1.50in; text-indent: 0.00in; margin-right: 1.50in; margin-top: 0; margin-bottom: 0; text-align: justify;">
<span style="font-size: 10pt">Originalmente aparecido en 
</span><span style="font-size: 10pt"><i>Proc. of the Winter 1993 USENIX Conf.,
</i></span><span style="font-size: 10pt">pp. 271-280,
San Diego, CA
</span></p><p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>




</div>

<div id="footer">
<br class="doNotDisplay doNotPrint" />

<div class="left"><a href="http://werc.cat-v.org/">Powered by werc</a></div>

<div class="right">
<form action="http://www.google.com/cse" id="cse-search-box" style="display: inline">
  <div style="display: inline">
    <input type="hidden" name="cx" value="partner-pub-2060328396151526:ea9sar-xttn" />
    <input type="hidden" name="ie" value="UTF-8" />
    <input type="text" name="q" size="32" />
    <input type="submit" name="sa" value="Search" />
  </div>
</form>
<script type="text/javascript" src="http://www.google.com/coop/cse/brand?form=cse-search-box&lang=en"></script></div>


<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-1220719-1");
pageTracker._setDomainName("cat-v.org");
pageTracker._trackPageview();

var pageTracker2 = _gat._getTracker("UA-1220719-12");
pageTracker2._trackPageview();
} catch(err) {}</script>
</div>
</body></html>
